package com.mldong.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mldong.auth.data.RoleDataScopeEnum;
import com.mldong.base.CommonPage;
import com.mldong.base.IRowHandler;
import com.mldong.base.YesNoEnum;
import com.mldong.modules.sys.dto.RolePageParam;
import com.mldong.modules.sys.dto.RoleParam;
import com.mldong.modules.sys.entity.RoleDept;
import com.mldong.modules.sys.vo.RoleVO;
import com.mldong.web.LoginUserHolder;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;

import com.mldong.util.LowCodeServiceUtil;
import com.mldong.modules.sys.entity.Role;
import com.mldong.modules.sys.mapper.RoleMapper;
import com.mldong.modules.sys.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author mldong
 * @since 2025-06-17
 */
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    private final RoleDeptServiceImpl roleDeptService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(RoleParam param) {
        param.setId(null);
        Role role = new Role();
        BeanUtil.copyProperties(param, role);
        if(StrUtil.isEmpty(param.getAppCode())){
            role.setAppCode(LoginUserHolder.getAppCode());
        }
        return super.save(role);
    }

    @Override
    public boolean update(RoleParam param) {
        Role role = new Role();
        BeanUtil.copyProperties(param, role);
        return LowCodeServiceUtil.updateById(baseMapper,role,RoleParam.class);
    }

    @Override
    public CommonPage<RoleVO> page(RolePageParam param) {
        IPage<RoleVO> page = param.buildMpPage();
        QueryWrapper queryWrapper = param.buildQueryWrapper();
        queryWrapper.eq("t.is_deleted",YesNoEnum.NO);
        if(StrUtil.isEmpty(param.getOrderBy())){
            queryWrapper.orderByAsc("t.sort");
        }
        List<RoleVO> list = baseMapper.selectCustom(page, queryWrapper);
        page.setRecords(list);
        return CommonPage.toPage(page, new IRowHandler<RoleVO>() {
            @Override
            public void handle(RoleVO roleVO) {
                roleVO.setDeptIdList(roleDeptService.getDeptIdListByRoleId(roleVO.getId()));
            }
        });
    }
    @Override
    public RoleVO findById(Long id) {
        RoleVO vo = baseMapper.findById(id);
        if(vo!=null) {
            vo.setDeptIdList(roleDeptService.getDeptIdListByRoleId(vo.getId()));
        }
        return vo;
    }

    @Override
    public void grantDataScope(Long roleId, Integer dataScope, List<Long> deptIdList) {
        Role role = new Role();
        role.setId(roleId);
        role.setDataScope(dataScope);
        boolean success = LowCodeServiceUtil.updateById(baseMapper,role, CollectionUtil.newArrayList("dataScope"),true);
        roleDeptService.remove(Wrappers.lambdaQuery(RoleDept.class).eq(RoleDept::getRoleId,roleId));
        if(deptIdList == null) return;
        if(success){
            if(CollectionUtil.isNotEmpty(deptIdList) && ObjectUtil.equals(dataScope, RoleDataScopeEnum.CUSTOM_DATA.getCode())){
                roleDeptService.saveBatch(deptIdList.stream().map(deptId -> {
                    RoleDept roleDept = new RoleDept();
                    roleDept.setRoleId(roleId);
                    roleDept.setDeptId(deptId);
                    return roleDept;
                }).collect(Collectors.toList()));
            }
        }
    }
}
